package scparser.factory.sceneFactory;

import java.io.BufferedReader;  
import java.io.IOException;
import javax.vecmath.Vector3d;

import camera.PinHoleCamera;
import camera.ThinlensCamera;

import lib.common.Constants;
import model.Scene;
import scparser.ParserHelper;
import scparser.factory.primitiveFactory.FactoryException;

public class SceneCameraFactory extends SceneFactory {

	public SceneCameraFactory(Scene scene) {
		super.scene = scene;
	}

	@Override
	public Object create(BufferedReader reader) throws FactoryException {
		String line = null;
		String typeString = null;
		Vector3d eye = null;
		Vector3d target =  null;
		Vector3d up =  null;
		Double aspect = null;
		Double fov = null;
		Double lensr = null;
		Double fdist = null;

		try {
			while ((line = reader.readLine()) != null) {
				line = line.trim();

				if (line.equals(Constants.S_CLOSE)) {
					break;
				}
				
				if (line.startsWith("type")) {
					typeString = ParserHelper.takeString(line, "type");
				} else if (line.startsWith("eye")) {
					eye = new Vector3d(ParserHelper.takePoint(line, "eye"));
				} else if (line.startsWith("target")) {
					target = new Vector3d(ParserHelper.takePoint(line, "target"));
				} else if (line.startsWith("up")) {
					up = new Vector3d(ParserHelper.takePoint(line, "up"));			
				} else if (line.startsWith("fov")) {
					// ignoring, fov default is 60, or taken from command argument
					fov = ParserHelper.takeDouble(line, "fov");
				} else if (line.startsWith("aspect")) {
					aspect = ParserHelper.takeDouble(line, "aspect");
				} else if (line.startsWith("fdist")) {
					fdist = ParserHelper.takeDouble(line, "fdist");
				} else if (line.startsWith("lensr")) {
					lensr = ParserHelper.takeDouble(line, "lensr");
				}				
			}
			
			if (fov == null) {
				fov = ParserHelper.fov;
			}
			
			if (!"pinhole".equals(typeString) && !"thinlens".equals(typeString)) {
				throw new FactoryException("Wrong camera type: " + typeString);
			}
			
			if( "pinhole".equals(typeString) )
				return new PinHoleCamera(target, eye, up, fov, aspect);
			else 
				return new ThinlensCamera(target, eye, up, fov, aspect, fdist, lensr);
		} catch (IOException e) {
			throw new FactoryException(e.getMessage());
		}
	}
}
